package org.microservice.redis.datascope.aspect;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.microservice.common.util.AuthUtil;
import org.microservice.common.util.CustomRuntimeException;
import org.microservice.common.util.constant.CacheConstant;
import org.microservice.common.util.constant.CommonConstant;
import org.microservice.common.util.constant.MqQueueConstant;
import org.microservice.redis.datascope.annotation.FilterDataScope;
import org.microservice.redis.util.RedisService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: 齐丹枫
 * Date: 2018/7/17
 * Time: 17:02
 * To change this template use File | Settings | File Templates.
 * Description:
 */
@Component
@Aspect
public class FilterDataScopeAspect {

    @Autowired
    private RedisService redisService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Before("@annotation(filterDataScope)")
    public Object setFilterCondition(JoinPoint point, FilterDataScope filterDataScope) throws Throwable {
        Object[] args = point.getArgs();
        /**
         * 验证方法参数是否是map类型
         */
        if(args[0] instanceof  Map){
            /**
             * 得到当前的用户名
             */
            String userName = AuthUtil.getUserName();

            if(userName.equals(CommonConstant.ADMIN_NAME)){
                return args;
            }
            Map<String, Object> params = (Map<String, Object>) args[0];

            params.put("self",userName);


            Map<String,List<Integer>> dataScope =null;
            /**
             * 从缓存中取出用户名的数据权限
             */
            if(!redisService.exists(CacheConstant.USER_INFO_KEY+userName)){

                rabbitTemplate.convertAndSend(MqQueueConstant.USER_DATA_SCOPE_CHANGE,userName);

                throw new CustomRuntimeException("用户缓存信息丢失");

            }else {
                Map<String, Object> objectMap = (Map<String, Object>) redisService.get(CacheConstant.USER_INFO_KEY + userName);

                dataScope= (Map<String, List<Integer>>) objectMap.get(CacheConstant.USER_DATA_SCOPE_KEY);
            }

            StringBuffer filterSql = new StringBuffer();
            boolean isScope = false;
            if( dataScope != null){
                 /**
                 * 得到注解参数值:控制类型
                 */
                String[] ctrlTypes = filterDataScope.ctrlTypes();

                /**
                 * 得到注解参数值：控制字段
                 */
                String[] columns = filterDataScope.columns();

                /**
                 * 得到连接条件 and ,or
                 */
                String[] whereType = filterDataScope.whereType();


                if(!filterDataScope.manyToMany()){
                    /**
                     * 向方法参数中添加权限控制参数
                     */

                    if(ctrlTypes.length>0 && columns.length >0 ){
                        for (int i = 0; i < ctrlTypes.length; i++) {
                            List<Integer> list = dataScope.get(ctrlTypes[i]);
                            if(list != null && list.size() > 0){
                                filterSql.append(" "+whereType[i]+" " + columns[i] + " in (" + StringUtils.join(list.toArray(), ",")+")  ");
                                isScope = true;
                            }
                        }
                    }
                }else{
                    for (int i = 0; i < ctrlTypes.length; i++) {
                        List<Integer> list = dataScope.get(ctrlTypes[i]);
                       // if(list != null && list.size() > 0){
                            params.put(ctrlTypes[i],list);
                            isScope = true;
                      //  }
                    }
                }





            }
            if(!isScope){
                filterSql.append(" and 1=2");
            }
            params.put("filterSql",filterSql.toString());

         return params;

        }else{
            throw  new CustomRuntimeException("参数类型必须为Map类型");
        }
    }






}
